package com.ls.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ls.config.redis.RedisClient;
import com.ls.config.satoken.SaTokenUtilPy;
import com.ls.controller.sms.model.SmsModel;
import com.ls.entity.*;
import com.ls.enums.LimitTypeEnum;
import com.ls.enums.RoleEnum;
import com.ls.enums.SignEnum;
import com.ls.exception.SysException;
import com.ls.mapper.OrderRecordMapper;
import com.ls.mapper.SmsRecordMapper;
import com.ls.mapper.SmsRuleMapper;
import com.ls.service.*;
import com.ls.utils.ResultData;
import com.ls.utils.sms.ReduceSmsUtil;
import com.ls.utils.sms.SendSmsModel;
import com.ls.utils.sms.SmsPyUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Random;

import static com.ls.constant.SystemConstants.*;

/**
 * <p>
 * 发送短信
 * </p>
 *
 * @author pengyu
 * @since 2024-10-12
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SmsServiceImpl extends ServiceImpl<SmsRecordMapper, SmsRecord> implements ISmsService {
    private final SmsRuleMapper smsRuleMapper;
    private final RedisClient redisClient;
    private final ISmsTemplateService smsTemplateService;
    private final IRuleTemplateService ruleTemplateService;
    private final ICustomerService customerService;
    private final IBlackListService blackListService;
    private final ReduceSmsUtil reduceSmsUtil;

    /**
     * 发送短信
     */
    @Override
    @Transactional(rollbackFor = SysException.class)
    public synchronized ResultData sendSms(SmsModel model) {

        log.info("发送短信传入数据:={}", model);
        //获取当前用户手机号和id
        Customer customer = SaTokenUtilPy.getCustomer();

        Customer customerInfo = customerService.getById(customer.getCustomerId());
        if (Objects.equals(customerInfo.getPhone(), model.getOuterPhone())) {
            log.info("不能添加自己");
            return ResultData.failure("不能添加自己");
        }
        //判断手机号格式是否正确
        if (!model.getOuterPhone().matches(PHONE_NUMBER_VALID_REGEX)) {
            log.info("手机号格式不正确");
            return ResultData.failure("手机号格式不正确");
        }
        if (model.getStartTime() != null && model.getEndTime() != null) {
            if (model.getStartTime().isAfter(model.getEndTime())) {
                log.info("开始时间不能大于结束时间");
                return ResultData.failure("开始时间不能大于结束时间");
            }
        }
        if (customerInfo.getSmsTotal() <= 0) {
            log.info("短信余额不足");
            return ResultData.failure("短信余额不足");
        }
        long blackCount = blackListService.count(new LambdaQueryWrapper<BlackList>()
                .eq(BlackList::getCustomerId, customerInfo.getCustomerId())
                .eq(BlackList::getBlackPhone, model.getOuterPhone()));
        RoleEnum roleEnum = RoleEnum.getRoleEnum(customerInfo.getRoleId());
        //黑名单生效，黑名单的号码可以不用发送短信
        if (blackCount > 0 && RoleEnum.MEMBER.equals(roleEnum)) {
            log.info("目标号码在黑名单中");
            return ResultData.failure("目标号码在黑名单中");
        }
        if (customer.getIsPlatformSign() == IS_PLATFORM_SIGN_FALSE
                && StringUtils.isBlank(customer.getSign())) {
            log.info("请设置有效签名或使用平台签名");
            return ResultData.failure("请设置有效签名或使用平台签名");
        }
        if (model.getStartTime() == null) {
            model.setStartTime(LocalDateTime.now());
        }
        //查询被叫号码是否在当前用户黑名单中
        //将数据存入通话记录表PhoneRecord
        PhoneRecord phoneRecord = new PhoneRecord();
        phoneRecord.setCustomerId(customerInfo.getCustomerId());
        phoneRecord.setCustomerPhone(customerInfo.getPhone());
        phoneRecord.setOuterPhone(model.getOuterPhone());
        phoneRecord.setOuterName(model.getOuterName());
        phoneRecord.setCallType(model.getCallType());
        phoneRecord.setStartTime(model.getStartTime());
        phoneRecord.setEndTime(model.getEndTime());
        Integer duration = null;
        if (model.getStartTime() != null && model.getEndTime() != null) {
            ZoneOffset offset = ZoneOffset.of("+8");
            duration = (int) (model.getEndTime().toEpochSecond(offset) - model.getStartTime().toEpochSecond(offset));
        }
        phoneRecord.setDuration(duration);
        phoneRecord.insert();
        //获取新增的通话记录id
        Long phoneRecordId = phoneRecord.getPRecordId();
        //查询符合条件的一条规则
        LocalDateTime now = LocalDateTime.now();
        log.info("当前时间:={}", now);
//        SmsRule smsRule = smsRuleMapper.selectOne(new LambdaQueryWrapper<SmsRule>().eq(SmsRule::getCustomerId, customerInfo.getCustomerId())
//                .eq(SmsRule::getCallType, model.getCallType()).eq(SmsRule::getValidFlag, VALID_TRUE).le(SmsRule::getStartTime, now)
//                .ge(SmsRule::getEndTime, now));
        LocalTime currentTime = now.toLocalTime();
        log.info("当前时间：{}", currentTime);
        // 修改查询条件
        SmsRule smsRule = smsRuleMapper.selectOne(new LambdaQueryWrapper<SmsRule>()
                .eq(SmsRule::getCustomerId, customerInfo.getCustomerId())
                .eq(SmsRule::getCallType, model.getCallType())
                .eq(SmsRule::getValidFlag, VALID_TRUE)
                .and(wrapper -> wrapper
                        // 当天时间段条件（start_time <= end_time）
                        .apply("start_time <= end_time")
                        .ge(SmsRule::getEndTime, currentTime)
                        .le(SmsRule::getStartTime, currentTime)
                        .or()
                        // 跨天时间段条件（start_time > end_time）
                        .apply("start_time > end_time")
                        .and(sub -> sub
                                .le(SmsRule::getStartTime, currentTime)
                                .or()
                                .ge(SmsRule::getEndTime, currentTime)
                        )
                )
        );
        log.info("查询到的规则:={}", smsRule);
        long count = 0;
        LocalDateTime startTime;
        LocalDateTime endTime;
        if (smsRule == null) {
            log.info("不符合发送条件,没有发送时间的启用规则");
            return ResultData.failure("不符合发送条件,没有发送时间的启用规则");
        }
        //发送限制类型: 1 无限制 2 每天一次 3 每周一次 4 每月一次
        //判断是否需要发送
        switch (LimitTypeEnum.getRoleEnum(smsRule.getLimitType())) {
            case NONE:
                count = 0;
                break;
            case DAY:
                //获取当天0点时间
                startTime = LocalDate.now().atStartOfDay();
                endTime = LocalDateTime.now();
                log.info("获取当天0点时间:={}", startTime);
                log.info("获取当天时间:={}", endTime);
                count = count(new LambdaQueryWrapper<SmsRecord>()
                        .eq(SmsRecord::getCustomerId, customerInfo.getCustomerId())
                        .eq(SmsRecord::getCallType, model.getCallType())
                        .eq(SmsRecord::getOuterPhone, model.getOuterPhone())
//                        .eq(SmsRecord::getSmsType, CHANNEL_TYPE_PLATFORM)
                        .in(SmsRecord::getSmsStatus, Arrays.asList(SMS_STATUS_TRUE,SMS_STATUS_SENDING))
                        .between(SmsRecord::getCreateTime, startTime, endTime));
                break;
            case WEEK:
                //获取现在时间星期一的时间戳
                LocalDate monday = LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
                // 将日期转换为当天的0点时间
                startTime = monday.atStartOfDay();
                endTime = LocalDateTime.now();
                log.info("获取当周0点时间:={}", startTime);
                count = count(new LambdaQueryWrapper<SmsRecord>()
                        .eq(SmsRecord::getCustomerId, customerInfo.getCustomerId())
                        .eq(SmsRecord::getCallType, model.getCallType())
                        .eq(SmsRecord::getOuterPhone, model.getOuterPhone())
//                        .eq(SmsRecord::getSmsType, CHANNEL_TYPE_PLATFORM)
                        .in(SmsRecord::getSmsStatus, Arrays.asList(SMS_STATUS_TRUE,SMS_STATUS_SENDING))
                        .between(SmsRecord::getCreateTime, startTime, endTime));
                break;
            case MONTH:
                //获取现在月份一号的时间戳
                // 获取当前月份的第一天
                LocalDate firstDayOfMonth = LocalDate.now().withDayOfMonth(1);
                // 转换为0点时间
                startTime = firstDayOfMonth.atStartOfDay();
                endTime = LocalDateTime.now();
                log.info("获取当月0点时间:={}", startTime);
                count = count(new LambdaQueryWrapper<SmsRecord>()
                        .eq(SmsRecord::getCustomerId, customerInfo.getCustomerId())
                        .eq(SmsRecord::getCallType, model.getCallType())
                        .eq(SmsRecord::getOuterPhone, model.getOuterPhone())
//                        .eq(SmsRecord::getSmsType, CHANNEL_TYPE_PLATFORM)
                        .in(SmsRecord::getSmsStatus, Arrays.asList(SMS_STATUS_TRUE,SMS_STATUS_SENDING))
                        .between(SmsRecord::getCreateTime, startTime, endTime));
                break;
        }
        log.info("发送数量：{}",count);

        if (count != 0) {
            log.info("不符合发送条件,超出发送限制");
            return ResultData.failure("不符合发送条件,超出发送限制");
        }
        //获取规则绑定的模板id
        List<RuleTemplate> ruleTemplateList = ruleTemplateService.list(new LambdaQueryWrapper<RuleTemplate>().eq(RuleTemplate::getRuleId, smsRule.getRuleId()).orderByDesc(RuleTemplate::getId));
        if (ruleTemplateList.isEmpty()) {
            return ResultData.failure("不符合发送条件,规则没有绑定的模板");
        }
        log.info("规则绑定的模板列表:={}", ruleTemplateList);
        //随机获取一个模板id
        Random random = new Random();
        int randomIndex = random.nextInt(ruleTemplateList.size());
//        int randomIndex = (int) (Math.random() * ruleTemplateList.size());
        log.info("随机获取的模板索引:={}", randomIndex);
        RuleTemplate selectedTemplate = ruleTemplateList.get(randomIndex);
        //根据id获取模板内容
        SmsTemplate smsTemplate = smsTemplateService.getById(selectedTemplate.getTemplateId());
        log.info("随机获取的模板内容:={}", smsTemplate);
        if (smsTemplate == null) {
            return ResultData.failure("不符合发送条件,没有匹配的模板内容");
        }
        try {
            String sign;
            if(customer.getIsPlatformSign()!=IS_PLATFORM_SIGN_FALSE){
                sign = SignEnum.getSign(customer.getIsPlatformSign());
            }else{
                sign = customer.getSign();
            }
            // 构建短信发送参数
            SendSmsModel sendSmsModel = new SendSmsModel(
                    model.getOuterPhone(),
                    "【" + sign + "】" + smsTemplate.getContent()
            );
            String content="【" + sign + "】" + smsTemplate.getContent();
            // 调用短信发送工具
            ResultData result = SmsPyUtil.sendCommonSms(sendSmsModel);
            log.info("短信发送结果:={}", JSON.toJSONString(result));
//            //获取需要扣除的短信长度
//            Integer number= ReduceSmsUtil.reduceNum(content);
//            SmsRecord smsRecord = new SmsRecord();
//            smsRecord.setPRecordId(phoneRecordId);
//            Integer recordId = (Integer) result.getData();
//            smsRecord.setRecordId(recordId.longValue());
//            smsRecord.setCustomerId(customerInfo.getCustomerId());
//            smsRecord.setCustomerPhone(customerInfo.getPhone());
//            smsRecord.setOuterPhone(model.getOuterPhone());
//            smsRecord.setOuterName(model.getOuterName());
//            smsRecord.setCallType(model.getCallType());
//            smsRecord.setSmsType(CHANNEL_TYPE_PLATFORM);
//            smsRecord.setTemplateCategory(TEMPLATE_CATEGORY_HANG_UP);
//            smsRecord.setContent(content);
//            smsRecord.setSmsReduceNum(number);
//            smsRecord.setCreateTime(now);
//            smsRecord.setSendTime(now);
//            if (!result.isSuccess()) {
//                smsRecord.setSmsStatus(SMS_STATUS_FALSE);
//            } else {
//                smsRecord.setSmsStatus(SMS_STATUS_SENDING);
//            }
//            smsRecord.insert();
//            if (!result.isSuccess()) {
//                return ResultData.failure("发送失败");
//            }
            //扣除短信余额
            Linkman linkman= new Linkman();
            linkman.setLinkmanPhone(model.getOuterPhone());
            linkman.setLinkmanName(model.getOuterName());
            reduceSmsUtil.reduceSms(customer.getCustomerId(),content,result,linkman,phoneRecordId,TEMPLATE_CATEGORY_HANG_UP,null,model.getCallType(),null,1);
        } catch (Exception e) {
            log.error("短信发送异常: {}", e);
            return ResultData.failure("系统繁忙，请稍后重试");
        }
        return ResultData.successMsg("短信发送成功");
    }


}
